import pygame
import sys
import math

# 初始化pygame
pygame.init()
pygame.font.init()

# 确保中文能正常显示
font = pygame.font.SysFont(['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC'], 48)
small_font = pygame.font.SysFont(['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC'], 24)

# 游戏窗口设置
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("双人火柴人打羽毛球")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
NET_COLOR = (200, 200, 200)
BACKGROUND_COLOR = (100, 200, 255)  # 浅蓝色背景

# 游戏参数
FPS = 60
GRAVITY = 0.2  # 重力加速度
PLAYER_SPEED = 5  # 玩家移动速度
JUMP_POWER = 10  # 跳跃力度
BALL_RADIUS = 10  # 羽毛球半径
BALL_INITIAL_SPEED = 8  # 羽毛球初始速度
NET_HEIGHT = 100  # 球网高度
NET_WIDTH = 5  # 球网宽度


# 玩家类（火柴人）
class Player:
    def __init__(self, x, y, color, controls):
        self.x = x
        self.y = y
        self.color = color
        self.width = 20
        self.height = 50
        self.velocity_y = 0
        self.jumping = False
        self.score = 0
        self.controls = controls  # 控制键配置
        self.hit_cooldown = 0  # 击球冷却

        # 火柴人身体部位尺寸
        self.head_radius = 10
        self.body_length = 30
        self.arm_length = 20
        self.leg_length = 25

    def update(self, court_height):
        keys = pygame.key.get_pressed()

        # 移动
        if keys[self.controls['left']]:
            self.x -= PLAYER_SPEED
        if keys[self.controls['right']]:
            self.x += PLAYER_SPEED

        # 跳跃
        if keys[self.controls['jump']] and not self.jumping:
            self.jumping = True
            self.velocity_y = -JUMP_POWER

        # 应用重力
        if self.jumping:
            self.velocity_y += GRAVITY
            self.y += self.velocity_y

            # 落地检测
            if self.y >= court_height - self.height:
                self.y = court_height - self.height
                self.velocity_y = 0
                self.jumping = False

        # 限制在屏幕内
        if self.x < 0:
            self.x = 0
        if self.x > WIDTH:
            self.x = WIDTH

        # 更新击球冷却
        if self.hit_cooldown > 0:
            self.hit_cooldown -= 1

    def draw(self, screen):
        # 绘制火柴人
        # 头部
        pygame.draw.circle(screen, self.color, (self.x, self.y - self.head_radius), self.head_radius)

        # 身体
        pygame.draw.line(screen, self.color, (self.x, self.y - self.head_radius),
                         (self.x, self.y + self.body_length), 3)

        # 手臂
        arm_y = self.y - self.head_radius + 10
        pygame.draw.line(screen, self.color, (self.x, arm_y),
                         (self.x - self.arm_length, arm_y + 10), 3)
        pygame.draw.line(screen, self.color, (self.x, arm_y),
                         (self.x + self.arm_length, arm_y + 10), 3)

        # 腿部
        leg_start_y = self.y + self.body_length
        pygame.draw.line(screen, self.color, (self.x, leg_start_y),
                         (self.x - self.leg_length // 2, leg_start_y + self.leg_length), 3)
        pygame.draw.line(screen, self.color, (self.x, leg_start_y),
                         (self.x + self.leg_length // 2, leg_start_y + self.leg_length), 3)

    def hit_ball(self, ball):
        if self.hit_cooldown > 0:
            return False

        # 火柴人的击球区域（头部周围）
        hit_distance = self.head_radius + BALL_RADIUS + 5

        # 计算与球的距离
        dx = ball.x - self.x
        dy = ball.y - (self.y - self.head_radius)
        distance = math.sqrt(dx * dx + dy * dy)

        if distance < hit_distance:
            # 击球方向（根据玩家位置和球的位置决定）
            angle = math.atan2(dy, dx)

            # 击球力度（根据跳跃状态调整）
            power = BALL_INITIAL_SPEED
            if self.jumping and self.velocity_y < 0:  # 上升阶段击球
                power *= 1.5

            # 更新球的速度
            ball.velocity_x = math.cos(angle) * power
            ball.velocity_y = math.sin(angle) * power

            # 设置击球冷却
            self.hit_cooldown = 15

            return True
        return False

    def reset_position(self, x, y):
        self.x = x
        self.y = y
        self.velocity_y = 0
        self.jumping = False


# 羽毛球类
class Ball:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.radius = BALL_RADIUS
        self.velocity_x = 0
        self.velocity_y = 0
        self.color = YELLOW

    def update(self, net_pos, court_height):
        # 应用重力
        self.velocity_y += GRAVITY

        # 更新位置
        self.x += self.velocity_x
        self.y += self.velocity_y

        # 左右边界碰撞
        if self.x - self.radius <= 0:
            self.x = self.radius
            self.velocity_x *= -0.8
        elif self.x + self.radius >= WIDTH:
            self.x = WIDTH - self.radius
            self.velocity_x *= -0.8

        # 顶部边界碰撞
        if self.y - self.radius <= 0:
            self.y = self.radius
            self.velocity_y *= -0.8

        # 球网碰撞
        net_x = net_pos[0]
        net_top = net_pos[1]
        net_bottom = net_pos[1] + NET_HEIGHT

        if (net_x - self.radius <= self.x <= net_x + NET_WIDTH + self.radius and
                net_top <= self.y + self.radius <= net_bottom):
            # 从左侧碰撞球网
            if self.velocity_x > 0 and self.x < net_x:
                self.x = net_x - self.radius
                self.velocity_x *= -0.8
            # 从右侧碰撞球网
            elif self.velocity_x < 0 and self.x > net_x + NET_WIDTH:
                self.x = net_x + NET_WIDTH + self.radius
                self.velocity_x *= -0.8

        # 球落在地上
        if self.y + self.radius >= court_height:
            self.y = court_height - self.radius
            self.velocity_y *= -0.5

            # 如果速度很小，停止运动
            if abs(self.velocity_y) < 0.5:
                self.velocity_y = 0

        # 空气阻力
        self.velocity_x *= 0.99
        self.velocity_y *= 0.99

    def draw(self, screen):
        # 绘制羽毛球
        pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.radius)

        # 绘制羽毛球的羽毛（简化）
        feather_length = self.radius * 0.6
        pygame.draw.line(screen, WHITE, (int(self.x), int(self.y)),
                         (int(self.x), int(self.y - feather_length)), 2)
        pygame.draw.line(screen, WHITE, (int(self.x), int(self.y)),
                         (int(self.x - feather_length * 0.7), int(self.y - feather_length * 0.7)), 2)
        pygame.draw.line(screen, WHITE, (int(self.x), int(self.y)),
                         (int(self.x + feather_length * 0.7), int(self.y - feather_length * 0.7)), 2)

    def reset_position(self, x, y):
        self.x = x
        self.y = y
        self.velocity_x = 0
        self.velocity_y = 0


# 游戏类
class Game:
    def __init__(self):
        self.player1 = Player(WIDTH // 4, HEIGHT - 100, RED,
                              {'left': pygame.K_a, 'right': pygame.K_d, 'jump': pygame.K_w})
        self.player2 = Player(WIDTH * 3 // 4, HEIGHT - 100, BLUE,
                              {'left': pygame.K_LEFT, 'right': pygame.K_RIGHT, 'jump': pygame.K_UP})
        self.ball = Ball(WIDTH // 2, HEIGHT // 2)
        self.net_position = (WIDTH // 2 - NET_WIDTH // 2, HEIGHT // 2 - NET_HEIGHT // 2)
        self.score_to_win = 5  # 获胜所需分数
        self.game_active = False
        self.winner = None
        self.serve_player = 1  # 发球方
        self.setup_round()

    def setup_round(self):
        # 重置玩家位置
        self.player1.reset_position(WIDTH // 4, HEIGHT - 100)
        self.player2.reset_position(WIDTH * 3 // 4, HEIGHT - 100)

        # 重置球的位置
        if self.serve_player == 1:
            self.ball.reset_position(WIDTH // 4, HEIGHT // 2)
        else:
            self.ball.reset_position(WIDTH * 3 // 4, HEIGHT // 2)

        # 游戏准备开始
        self.game_active = True
        self.winner = None

    def update(self):
        if not self.game_active:
            return

        # 更新玩家
        self.player1.update(HEIGHT)
        self.player2.update(HEIGHT)

        # 更新球
        self.ball.update(self.net_position, HEIGHT)

        # 检测玩家击球
        p1_hit = self.player1.hit_ball(self.ball)
        p2_hit = self.player2.hit_ball(self.ball)

        # 检查得分
        if self.ball.y + self.ball.radius >= HEIGHT:
            # 判断球落在哪个半场
            if self.ball.x < WIDTH // 2:
                # 球落在玩家1的半场，玩家2得分
                self.player2.score += 1
                self.serve_player = 2
            else:
                # 球落在玩家2的半场，玩家1得分
                self.player1.score += 1
                self.serve_player = 1

            # 检查是否有玩家获胜
            if self.player1.score >= self.score_to_win:
                self.winner = self.player1
                self.game_active = False
            elif self.player2.score >= self.score_to_win:
                self.winner = self.player2
                self.game_active = False
            else:
                # 继续下一轮
                pygame.time.delay(1000)
                self.setup_round()

    def draw(self, screen):
        # 绘制背景
        screen.fill(BACKGROUND_COLOR)

        # 绘制场地分隔线
        pygame.draw.line(screen, WHITE, (0, HEIGHT - 10), (WIDTH, HEIGHT - 10), 5)

        # 绘制球网
        pygame.draw.rect(screen, NET_COLOR,
                         (self.net_position[0], self.net_position[1],
                          NET_WIDTH, NET_HEIGHT))

        # 绘制球员
        self.player1.draw(screen)
        self.player2.draw(screen)

        # 绘制球
        self.ball.draw(screen)

        # 绘制得分
        score_text = font.render(f"{self.player1.score} : {self.player2.score}", True, WHITE)
        screen.blit(score_text, (WIDTH // 2 - score_text.get_width() // 2, 20))

        # 绘制玩家控制提示
        p1_controls = small_font.render("玩家1: A/D移动, W跳跃", True, WHITE)
        p2_controls = small_font.render("玩家2: ←/→移动, ↑跳跃", True, WHITE)

        screen.blit(p1_controls, (20, 20))
        screen.blit(p2_controls, (WIDTH - p2_controls.get_width() - 20, 20))

        # 绘制发球提示
        if not self.game_active and self.winner is None:
            serve_text = font.render(f"玩家{self.serve_player}发球", True, WHITE)
            screen.blit(serve_text, (WIDTH // 2 - serve_text.get_width() // 2, HEIGHT // 2 - 50))
            start_text = small_font.render("按空格键开始", True, WHITE)
            screen.blit(start_text, (WIDTH // 2 - start_text.get_width() // 2, HEIGHT // 2 + 20))

        # 绘制获胜信息
        if self.winner:
            winner_text = font.render(f"玩家{1 if self.winner == self.player1 else 2}获胜!", True, WHITE)
            screen.blit(winner_text, (WIDTH // 2 - winner_text.get_width() // 2, HEIGHT // 2 - 50))
            restart_text = small_font.render("按R键重新开始", True, WHITE)
            screen.blit(restart_text, (WIDTH // 2 - restart_text.get_width() // 2, HEIGHT // 2 + 20))

    def handle_event(self, event):
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE and not self.game_active and self.winner is None:
                # 开始游戏/发球
                if self.serve_player == 1:
                    self.ball.velocity_x = BALL_INITIAL_SPEED
                    self.ball.velocity_y = -BALL_INITIAL_SPEED / 2
                else:
                    self.ball.velocity_x = -BALL_INITIAL_SPEED
                    self.ball.velocity_y = -BALL_INITIAL_SPEED / 2
                self.game_active = True
            elif event.key == pygame.K_r and self.winner:
                # 重新开始游戏
                self.player1.score = 0
                self.player2.score = 0
                self.serve_player = 1
                self.setup_round()


# 主函数
def main():
    clock = pygame.time.Clock()
    game = Game()

    running = True
    while running:
        clock.tick(FPS)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            game.handle_event(event)

        # 更新游戏
        game.update()

        # 绘制游戏
        game.draw(screen)

        # 更新显示
        pygame.display.flip()

    pygame.quit()
    sys.exit()


if __name__ == "__main__":
    main()